package utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * @author ljc
 */
public class MD5Util {
	private final static String HEX_NUMS_STR = "0123456789ABCDEF";
	private final static Integer SALT_LENGTH = 0;
	private final static String ENCODING = "UTF-8";

	/**
	 * 将16进制字符串转换成数组
	 *
	 * @return byte[]
	 * @author jacob
	 * */
	public static byte[] hexStringToByte(String hex) {
		/* len为什么是hex.length() / 2 ?
		 * 首先，hex是一个字符串，里面的内容是像16进制那样的char数组
		 * 用2个16进制数字可以表示1个byte，所以要求得这些char[]可以转化成什么样的byte[]，首先可以确定的就是长度为这个char[]的一半
		 */
		int len = (hex.length() / 2);
		byte[] result = new byte[len];
		char[] hexChars = hex.toCharArray();
		for (int i = 0; i < len; i++) {
			int pos = i * 2;
			result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4 | HEX_NUMS_STR
					.indexOf(hexChars[pos + 1]));
		}
		return result;
	}

	/**
	 * 将数组转换成16进制字符串
	 *
	 * @return String
	 * @author jacob
	 *
	 * */
	public static String byteToHexString(byte[] salt){
		StringBuilder hexString = new StringBuilder();
		for (byte b : salt) {
			String hex = Integer.toHexString(b & 0xFF);
			if(hex.length() == 1){
				hex = '0' + hex;
			}
			hexString.append(hex.toUpperCase());
		}

		return hexString.toString();
	}


	/**
	 * 获得md5之后的16进制字符
	 * @param password 用户输入密码字符
	 * @return String md5加密后密码字符
	 * @throws NoSuchAlgorithmException 抛出加密异常
	 * @throws UnsupportedEncodingException 抛出编码异常
	 */
	public static String getEncryptedPwd(String password)
			throws NoSuchAlgorithmException, UnsupportedEncodingException{
		//拿到一个随机数组，作为盐
		byte[] pwd ;
		SecureRandom sc= new SecureRandom();
		byte[] salt = new byte[SALT_LENGTH];
		sc.nextBytes(salt);

		//声明摘要对象，并生成
		MessageDigest md = MessageDigest.getInstance("MD5");
		//计算MD5函数
		md.update(salt);
		//password.getBytes("UTF-8")将输入密码变成byte数组，即将某个数装换成一个16进制数
		md.update(password.getBytes(ENCODING));
		//计算后获得字节数组,这就是那128位了即16个元素
		byte[] digest = md.digest();
		pwd = new byte[salt.length + digest.length];
		System.arraycopy(salt, 0, pwd, 0, SALT_LENGTH);
		System.arraycopy(digest, 0, pwd, SALT_LENGTH, digest.length);
		return byteToHexString(pwd);
	}

}